package com.mzj.saas.commons.util;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.concurrent.ConcurrentHashMap;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class XmlUtils {

	// private static Logger logger = Logger.getLogger(XmlUtils.class);

	static ConcurrentHashMap<String, JAXBContext> jaxbContextMap = new ConcurrentHashMap<String, JAXBContext>();

	/**
	 * JavaBean转换成xml 默认编码UTF-8
	 * 
	 * @param obj
	 * @param writer
	 * @return
	 */
	public static String convertToXml(Object obj) {
		return convertToXml(obj, "UTF-8");
	}

	/**
	 * JavaBean转换成xml
	 * 
	 * @param obj
	 * @param encoding
	 * @return
	 */
	public static String convertToXml(Object obj, String encoding) {
		String result = null;
		StringWriter writer = null;
		try {
			JAXBContext context = JAXBContext.newInstance(obj.getClass());
			Marshaller marshaller = context.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
			writer = new StringWriter();
			marshaller.marshal(obj, writer);
			result = writer.toString();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (writer != null) {
					writer.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

	/**
	 * xml转换成JavaBean
	 * 
	 * @param xml
	 * @param c
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T converyToObj(InputStream is, Class<T> c) {
		T t = null;
		try {
			JAXBContext jaxbContext = getJaxbContext(c);
			Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
			t = (T) unmarshaller.unmarshal(is);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (is != null) {
					is.close();
				}
			} catch (Exception e) {

			}
		}
		return t;
	}

	public static <T> T converyToObj(String xml, Class<T> c) {
		
		InputStream is = new ByteArrayInputStream(xml.getBytes());
		return converyToObj(is, c);
	}

	private static <T> JAXBContext getJaxbContext(Class<T> c) {
		JAXBContext jaxbContext = jaxbContextMap.get(c.getClass().getName());
		try {
			if (jaxbContext == null) {
				jaxbContext = JAXBContext.newInstance(c);
			}
			JAXBContext older = jaxbContextMap.putIfAbsent(c.getClass().getName(), jaxbContext);
			if (older != null) {
				jaxbContext = older;
			}
		} catch (Exception e) {

		}
		return jaxbContext;
	}
}
